using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Management;
using System.Runtime.InteropServices;
using System.Text;

namespace Hotel.UI.Common
{
    /// <summary>
    /// 获取系统信息、电脑CPU、磁盘、网卡、内存等相关信息辅助�?
    /// </summary>
    public class HardwareInfoHelper
    {
        public HardwareInfoHelper()
        {


        }

        [DllImport("kernel32.dll", CharSet = CharSet.None, ExactSpelling = false, SetLastError = true)]
        private static extern int CloseHandle(IntPtr intptr_0);

        [DllImport("kernel32.dll", CharSet = CharSet.None, ExactSpelling = false, SetLastError = true)]
        private static extern IntPtr CreateFile(string string_0, uint uint_0, uint uint_1, IntPtr intptr_0, uint uint_2, uint uint_3, IntPtr intptr_1);

        [DllImport("kernel32.dll", CharSet = CharSet.None, ExactSpelling = false)]
        private static extern int DeviceIoControl(IntPtr intptr_0, uint uint_0, IntPtr intptr_1, uint uint_1, ref HardwareInfoHelper.Struct191 struct191_0, uint uint_2, ref uint uint_3, [Out] IntPtr intptr_2);

        [DllImport("kernel32.dll", CharSet = CharSet.None, EntryPoint = "DeviceIoControl", ExactSpelling = false)]
        private static extern int DeviceIoControl_1(IntPtr intptr_0, uint uint_0, ref HardwareInfoHelper.Struct193 struct193_0, uint uint_1, ref HardwareInfoHelper.Struct195 struct195_0, uint uint_2, ref uint uint_3, [Out] IntPtr intptr_1);

        /// <summary>
        /// 获取计算机名
        /// </summary>
        public static string GetComputerName()
        {
            return Environment.MachineName;
        }

        /// <summary>
        /// 获取CPU的ID
        /// </summary>
        /// <returns></returns>
        public static string GetCPUId()
        {
            string str = "";
            try
            {
                ManagementObjectCollection.ManagementObjectEnumerator enumerator = (new ManagementClass("Win32_Processor")).GetInstances().GetEnumerator();
                try
                {
                    if (enumerator.MoveNext())
                    {
                        ManagementObject current = (ManagementObject)enumerator.Current;
                        str = current.Properties["ProcessorId"].Value.ToString();
                    }
                }
                finally
                {
                    if (enumerator != null)
                    {
                        ((IDisposable)enumerator).Dispose();
                    }
                }
            }
            catch
            {
                str = "078BFBFF00020FC1";
            }
            return str;
        }

        /// <summary>
        /// 获得Cpu使用�?
        /// </summary>
        public static int GetCpuUsage()
        {
            return HardwareInfoHelper.CpuUsage.Create().Query();
        }

        /// <summary>
        /// 获取硬盘ID
        /// </summary>
        /// <returns></returns>
        public static string GetDiskID()
        {
            string str = "";
            foreach (ManagementObject instance in (new ManagementClass("Win32_DiskDrive")).GetInstances())
            {
                str = instance.Properties["signature"].Value.ToString();
            }
            return str;
        }

        /// <summary>
        /// 获取硬盘Model的信�?
        /// </summary>
        public static string GetDiskModel()
        {
            string empty = string.Empty;
            ManagementClass managementClass = new ManagementClass("Win32_DiskDrive");
            try
            {
                foreach (ManagementObject instance in managementClass.GetInstances())
                {
                    empty = (string)instance.Properties["Model"].Value;
                }
            }
            finally
            {
                if (managementClass != null)
                {
                    ((IDisposable)managementClass).Dispose();
                }
            }
            return empty;
        }

        /// <summary>
        /// 获取IP地址
        /// </summary>
        public static string GetIPAddress()
        {
            string str = "";
            ManagementObjectCollection.ManagementObjectEnumerator enumerator = (new ManagementClass("Win32_NetworkAdapterConfiguration")).GetInstances().GetEnumerator();
            try
            {
                while (true)
                {
                    if (enumerator.MoveNext())
                    {
                        ManagementObject current = (ManagementObject)enumerator.Current;
                        if ((bool)current["IPEnabled"])
                        {
                            Array value = (Array)current.Properties["IpAddress"].Value;
                            str = value.GetValue(0).ToString();
                            break;
                        }
                    }
                    else
                    {
                        break;
                    }
                }
            }
            finally
            {
                if (enumerator != null)
                {
                    ((IDisposable)enumerator).Dispose();
                }
            }
            return str;
        }

        /// <summary>
        /// 获取MAC地址
        /// </summary>
        /// <returns></returns>
        public static string GetMacAddress()
        {
            string str = "";
            ManagementObjectCollection.ManagementObjectEnumerator enumerator = (new ManagementClass("Win32_NetworkAdapterConfiguration")).GetInstances().GetEnumerator();
            try
            {
                while (true)
                {
                    if (enumerator.MoveNext())
                    {
                        ManagementObject current = (ManagementObject)enumerator.Current;
                        if ((bool)current["IPEnabled"])
                        {
                            str = current["MacAddress"].ToString();
                            break;
                        }
                    }
                    else
                    {
                        break;
                    }
                }
            }
            finally
            {
                if (enumerator != null)
                {
                    ((IDisposable)enumerator).Dispose();
                }
            }
            return str;
        }

        /// <summary>
        /// 获取PC类型
        /// </summary>
        public static string GetSystemType()
        {
            string str = "";
            foreach (ManagementObject instance in (new ManagementClass("Win32_ComputerSystem")).GetInstances())
            {
                str = instance["SystemType"].ToString();
            }
            return str;
        }

        /// <summary>
        /// 获取物理内存
        /// </summary>
        public static string GetTotalPhysicalMemory()
        {
            string str = "";
            foreach (ManagementObject instance in (new ManagementClass("Win32_ComputerSystem")).GetInstances())
            {
                str = instance["TotalPhysicalMemory"].ToString();
            }
            return str;
        }

        /// <summary>
        /// 返回USB盘符列表
        /// </summary>
        public static List<string> GetUSBDriveLetters()
        {
            List<string> strs = new List<string>();
            foreach (ManagementObject managementObject in (new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive WHERE InterfaceType='USB'")).Get())
            {
                foreach (ManagementObject related in managementObject.GetRelated("Win32_DiskPartition"))
                {
                    foreach (ManagementObject related1 in related.GetRelated("Win32_LogicalDisk"))
                    {
                        strs.Add(related1["DeviceID"].ToString());
                    }
                }
            }
            return strs;
        }

        /// <summary>
        /// 获取操作系统的登录用户名
        /// </summary>
        public static string GetUserName()
        {
            return Environment.UserName;
        }

        [DllImport("kernel32.dll", CharSet = CharSet.None, ExactSpelling = false)]
        private static extern int GetVolumeInformation(string string_0, string string_1, int int_0, ref int int_1, int int_2, int int_3, string string_2, int int_4);

        /// <summary>
        /// 获得盘符为drvID的硬盘序列号，缺省为C
        /// </summary>
        /// <param name="drvID">盘符，如"C"</param>
        /// <returns></returns>
        public static string HDVal(string drvID)
        {
            int num = 0;
            string str = null;
            string str1 = null;
            HardwareInfoHelper.GetVolumeInformation(string.Concat(drvID, ":\\"), str, 0x100, ref num, 0, 0, str1, 0x100);
            return num.ToString();
        }

        /// <summary>
        /// 获取默认C盘的磁盘序列�?
        /// </summary>
        /// <returns></returns>
        public static string HDVal()
        {
            return HardwareInfoHelper.HDVal("C");
        }

        public static string smethod_0()
        {
            object value = Registry.LocalMachine.OpenSubKey("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0").GetValue("ProcessorNameString");
            return ((string)value).TrimStart(new char[0]);
        }

        private static HardDiskInfo smethod_1(byte byte_0)
        {
            HardwareInfoHelper.Struct191 struct191 = new HardwareInfoHelper.Struct191();
            HardwareInfoHelper.Struct193 byte0 = new HardwareInfoHelper.Struct193();
            HardwareInfoHelper.Struct195 struct195 = new HardwareInfoHelper.Struct195();
            uint num = 0;
            IntPtr intPtr = HardwareInfoHelper.CreateFile("\\\\.\\Smartvsd", 0, 0, IntPtr.Zero, 1, 0, IntPtr.Zero);
            if (intPtr == IntPtr.Zero)
            {
                throw new Exception("Open smartvsd.vxd failed.");
            }
            if (0 == HardwareInfoHelper.DeviceIoControl(intPtr, 0x74080, IntPtr.Zero, 0, ref struct191, (uint)Marshal.SizeOf(struct191), ref num, IntPtr.Zero))
            {
                HardwareInfoHelper.CloseHandle(intPtr);
                throw new Exception("DeviceIoControl failed:DFP_GET_VERSION");
            }
            if (0 == (struct191.uint_0 & 1))
            {
                HardwareInfoHelper.CloseHandle(intPtr);
                throw new Exception("Error: IDE identify command not supported.");
            }
            if (0 == (byte_0 & 1))
            {
                byte0.struct192_0.byte_5 = 160;
            }
            else
            {
                byte0.struct192_0.byte_5 = 176;
            }
            if (0L != ((ulong)struct191.uint_0 & (ulong)(long)(16 >> (byte_0 & 31))))
            {
                HardwareInfoHelper.CloseHandle(intPtr);
                throw new Exception(string.Format("Drive {0} is a ATAPI device, we don''t detect it", byte_0 + 1));
            }
            byte0.struct192_0.byte_6 = 236;
            byte0.byte_0 = byte_0;
            byte0.struct192_0.byte_1 = 1;
            byte0.struct192_0.byte_2 = 1;
            byte0.uint_0 = 0x200;
            if (0 == HardwareInfoHelper.DeviceIoControl_1(intPtr, 0x7c088, ref byte0, (uint)Marshal.SizeOf(byte0), ref struct195, (uint)Marshal.SizeOf(struct195), ref num, IntPtr.Zero))
            {
                HardwareInfoHelper.CloseHandle(intPtr);
                throw new Exception("DeviceIoControl failed: DFP_RECEIVE_DRIVE_DATA");
            }
            HardwareInfoHelper.CloseHandle(intPtr);
            return HardwareInfoHelper.smethod_3(struct195.struct196_0);
        }

        private static HardDiskInfo smethod_2(byte byte_0)
        {
            HardwareInfoHelper.Struct191 struct191 = new HardwareInfoHelper.Struct191();
            HardwareInfoHelper.Struct193 byte0 = new HardwareInfoHelper.Struct193();
            HardwareInfoHelper.Struct195 struct195 = new HardwareInfoHelper.Struct195();
            uint num = 0;
            IntPtr intPtr = HardwareInfoHelper.CreateFile(string.Format("\\\\.\\PhysicalDrive{0}", byte_0), 3221225472u, 3, IntPtr.Zero, 3, 0, IntPtr.Zero);
            if (intPtr == IntPtr.Zero)
            {
                throw new Exception("CreateFile faild.");
            }
            if (0 == HardwareInfoHelper.DeviceIoControl(intPtr, 0x74080, IntPtr.Zero, 0, ref struct191, (uint)Marshal.SizeOf(struct191), ref num, IntPtr.Zero))
            {
                HardwareInfoHelper.CloseHandle(intPtr);
                throw new Exception(string.Format("Drive {0} may not exists.", byte_0 + 1));
            }
            if (0 == (struct191.uint_0 & 1))
            {
                HardwareInfoHelper.CloseHandle(intPtr);
                throw new Exception("Error: IDE identify command not supported.");
            }
            if (0 == (byte_0 & 1))
            {
                byte0.struct192_0.byte_5 = 160;
            }
            else
            {
                byte0.struct192_0.byte_5 = 176;
            }
            if (0L != ((ulong)struct191.uint_0 & (ulong)(long)(16 >> (byte_0 & 31))))
            {
                HardwareInfoHelper.CloseHandle(intPtr);
                throw new Exception(string.Format("Drive {0} is a ATAPI device, we don''t detect it.", byte_0 + 1));
            }
            byte0.struct192_0.byte_6 = 236;
            byte0.byte_0 = byte_0;
            byte0.struct192_0.byte_1 = 1;
            byte0.struct192_0.byte_2 = 1;
            byte0.uint_0 = 0x200;
            if (0 == HardwareInfoHelper.DeviceIoControl_1(intPtr, 0x7c088, ref byte0, (uint)Marshal.SizeOf(byte0), ref struct195, (uint)Marshal.SizeOf(struct195), ref num, IntPtr.Zero))
            {
                HardwareInfoHelper.CloseHandle(intPtr);
                throw new Exception("DeviceIoControl failed: DFP_RECEIVE_DRIVE_DATA");
            }
            HardwareInfoHelper.CloseHandle(intPtr);
            return HardwareInfoHelper.smethod_3(struct195.struct196_0);
        }

        private static HardwareInfoHelper.HardDiskInfo smethod_3(HardwareInfoHelper.Struct196 struct196_0)
        {
            HardwareInfoHelper.HardDiskInfo uint1 = new HardwareInfoHelper.HardDiskInfo();
            HardwareInfoHelper.smethod_4(struct196_0.byte_2);
            uint1.ModuleNumber = Encoding.ASCII.GetString(struct196_0.byte_2).Trim();
            HardwareInfoHelper.smethod_4(struct196_0.byte_1);
            uint1.Firmware = Encoding.ASCII.GetString(struct196_0.byte_1).Trim();
            HardwareInfoHelper.smethod_4(struct196_0.byte_0);
            uint1.SerialNumber = Encoding.ASCII.GetString(struct196_0.byte_0).Trim();
            uint1.Capacity = struct196_0.uint_1 / 2 / 0x400;
            return uint1;
        }

        private static void smethod_4(byte[] byte_0)
        {
            for (int i = 0; i < (int)byte_0.Length; i = i + 2)
            {
                byte byte0 = byte_0[i];
                byte_0[i] = byte_0[i + 1];
                byte_0[i + 1] = byte0;
            }
        }

        public static HardDiskInfo smethod_5(byte driveIndex)
        {
            HardwareInfoHelper.HardDiskInfo hardDiskInfo;
            switch (Environment.OSVersion.Platform)
            {
                case PlatformID.Win32S:
                    {
                        throw new NotSupportedException("Win32s is not supported.");
                    }
                case PlatformID.Win32Windows:
                    {
                        hardDiskInfo = HardwareInfoHelper.smethod_1(driveIndex);
                        break;
                    }
                case PlatformID.Win32NT:
                    {
                        hardDiskInfo = HardwareInfoHelper.smethod_2(driveIndex);
                        break;
                    }
                case PlatformID.WinCE:
                    {
                        throw new NotSupportedException("WinCE is not supported.");
                    }
                default:
                    {
                        throw new NotSupportedException("Unknown Platform.");
                    }
            }
            return hardDiskInfo;
        }

        public class CpuUsage9x : CpuUsage
        {
            private RegistryKey registryKey_0;

            public CpuUsage9x()
            {


                try
                {
                    RegistryKey registryKey = Registry.PerformanceData.OpenSubKey("PerfStats\\StartStat", false);
                    if (registryKey == null)
                    {
                        throw new NotSupportedException();
                    }
                    registryKey.GetValue("KERNEL\\CPUUsage");
                    registryKey.Close();
                    this.registryKey_0 = Registry.DynData.OpenSubKey("PerfStats\\StatData", false);
                    if (this.registryKey_0 == null)
                    {
                        throw new NotSupportedException();
                    }
                }
                catch (NotSupportedException notSupportedException)
                {
                    throw notSupportedException;
                }
                catch (Exception exception)
                {
                    throw new NotSupportedException("Error while querying the system information.", exception);
                }
            }


            ~CpuUsage9x()
            {
                try
                {
                    try
                    {
                        this.registryKey_0.Close();
                    }
                    catch
                    {
                    }
                    try
                    {
                        RegistryKey registryKey = Registry.DynData.OpenSubKey("PerfStats\\StopStat", false);
                        registryKey.GetValue("KERNEL\\CPUUsage", false);
                        registryKey.Close();
                    }
                    catch
                    {
                    }
                }
                finally
                {
                }
            }

            public override int Query()
            {
                int value;
                try
                {
                    value = (int)this.registryKey_0.GetValue("KERNEL\\CPUUsage");
                }
                catch (Exception exception)
                {
                    throw new NotSupportedException("Error while querying the system information.", exception);
                }
                return value;
            }
        }

        public sealed class CpuUsageNt : CpuUsage
        {
            private long long_0;

            private long aTbwhnunec;

            private double double_0;

            public CpuUsageNt()
            {


                byte[] numArray = new byte[32];
                byte[] numArray1 = new byte[0x138];
                byte[] numArray2 = new byte[44];
                if (HardwareInfoHelper.CpuUsageNt.NtQuerySystemInformation(3, numArray, (int)numArray.Length, IntPtr.Zero) != 0)
                {
                    throw new NotSupportedException();
                }
                if (HardwareInfoHelper.CpuUsageNt.NtQuerySystemInformation(2, numArray1, (int)numArray1.Length, IntPtr.Zero) != 0)
                {
                    throw new NotSupportedException();
                }
                if (HardwareInfoHelper.CpuUsageNt.NtQuerySystemInformation(0, numArray2, (int)numArray2.Length, IntPtr.Zero) != 0)
                {
                    throw new NotSupportedException();
                }
                this.long_0 = BitConverter.ToInt64(numArray1, 0);
                this.aTbwhnunec = BitConverter.ToInt64(numArray, 8);
                this.double_0 = (double)numArray2[40];
            }

            [DllImport("ntdll", CharSet = CharSet.None, ExactSpelling = false)]
            private static extern int NtQuerySystemInformation(int int_0, byte[] byte_0, int int_1, IntPtr intptr_0);

            public override int Query()
            {
                byte[] numArray = new byte[32];
                byte[] numArray1 = new byte[0x138];
                if (HardwareInfoHelper.CpuUsageNt.NtQuerySystemInformation(3, numArray, (int)numArray.Length, IntPtr.Zero) != 0)
                {
                    throw new NotSupportedException();
                }
                if (HardwareInfoHelper.CpuUsageNt.NtQuerySystemInformation(2, numArray1, (int)numArray1.Length, IntPtr.Zero) != 0)
                {
                    throw new NotSupportedException();
                }
                double num = (double)(BitConverter.ToInt64(numArray1, 0) - this.long_0);
                double num1 = (double)(BitConverter.ToInt64(numArray, 8) - this.aTbwhnunec);
                if (num1 != 0)
                {
                    num = num / num1;
                }
                num = 100 - num * 100 / this.double_0 + 0.5;
                this.long_0 = BitConverter.ToInt64(numArray1, 0);
                this.aTbwhnunec = BitConverter.ToInt64(numArray, 8);
                return (int)num;
            }
        }

        /// <summary>
        /// 定义一个抽象基类实现CPU使用率计数器
        /// </summary>
        public abstract class CpuUsage
        {
            private static HardwareInfoHelper.CpuUsage cpuUsage_0;

            static CpuUsage()
            {

                HardwareInfoHelper.CpuUsage.cpuUsage_0 = null;
            }

            protected CpuUsage()
            {


            }

            /// <summary>
            /// Creates and returns a CpuUsage instance that can be used to query the CPU time on this operating system.
            /// </summary>
            /// <returns>An instance of the CpuUsage class.</returns>
            /// <exception cref="T:System.NotSupportedException">This platform is not supported -or- initialization of the CPUUsage object failed.</exception>
            public static HardwareInfoHelper.CpuUsage Create()
            {
                if (HardwareInfoHelper.CpuUsage.cpuUsage_0 == null)
                {
                    if (Environment.OSVersion.Platform != PlatformID.Win32NT)
                    {
                        if (Environment.OSVersion.Platform != PlatformID.Win32Windows)
                        {
                            throw new NotSupportedException();
                        }
                        HardwareInfoHelper.CpuUsage.cpuUsage_0 = new HardwareInfoHelper.CpuUsage9x();
                    }
                    else
                    {
                        HardwareInfoHelper.CpuUsage.cpuUsage_0 = new HardwareInfoHelper.CpuUsageNt();
                    }
                }
                return HardwareInfoHelper.CpuUsage.cpuUsage_0;
            }

            /// <summary>
            /// Determines the current average CPU load.
            /// </summary>
            /// <returns>An integer that holds the CPU load percentage.</returns>
            /// <exception cref="T:System.NotSupportedException">One of the system calls fails. The CPU time can not be obtained.</exception>
            public abstract int Query();
        }

        /// <summary>
        /// 硬盘信息
        /// </summary>
        [Serializable]
        public struct HardDiskInfo
        {
            /// <summary>
            /// 型号
            /// </summary>
            public string ModuleNumber;

            /// <summary>
            /// 固件版本
            /// </summary>
            public string Firmware;

            /// <summary>
            /// 序列�?
            /// </summary>
            public string SerialNumber;

            /// <summary>
            /// 容量，以M为单�?
            /// </summary>
            public uint Capacity;
        }

        internal struct Struct191
        {
            public byte byte_0;

            public byte byte_1;

            public byte byte_2;

            public byte byte_3;

            public uint uint_0;

            public uint[] uint_1;
        }

        internal struct Struct192
        {
            public byte byte_0;

            public byte byte_1;

            public byte byte_2;

            public byte byte_3;

            public byte byte_4;

            public byte byte_5;

            public byte byte_6;

            public byte byte_7;
        }

        internal struct Struct193
        {
            public uint uint_0;

            public HardwareInfoHelper.Struct192 struct192_0;

            public byte byte_0;

            public byte[] byte_1;

            public uint[] uint_1;

            public byte byte_2;
        }

        internal struct Struct194
        {
            public byte byte_0;

            public byte byte_1;

            public byte[] byte_2;

            public uint[] uint_0;
        }

        internal struct Struct195
        {
            public uint uint_0;

            public HardwareInfoHelper.Struct194 struct194_0;

            public HardwareInfoHelper.Struct196 struct196_0;
        }

        internal struct Struct196
        {
            public ushort ushort_0;

            public ushort ushort_1;

            public ushort ushort_2;

            public ushort ushort_3;

            public ushort YhGerkbnSd;

            public ushort ushort_4;

            public ushort ushort_5;

            public ushort[] ushort_6;

            public byte[] byte_0;

            public ushort ushort_7;

            public ushort ushort_8;

            public ushort ushort_9;

            public byte[] byte_1;

            public byte[] byte_2;

            public ushort ushort_10;

            public ushort ushort_11;

            public ushort ushort_12;

            public ushort ushort_13;

            public ushort ushort_14;

            public ushort ushort_15;

            public ushort ushort_16;

            public ushort ushort_17;

            public ushort ushort_18;

            public ushort ushort_19;

            public uint uint_0;

            public ushort ushort_20;

            public uint uint_1;

            public ushort ushort_21;

            public ushort ushort_22;

            public byte[] byte_3;
        }
    }
}